package com.zlm.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.security.SpringSessionBackedSessionRegistry;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * security配置
 */

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // 操作session的
    @Resource
    private FindByIndexNameSessionRepository findByIndexNameSessionRepository;


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .and()
                .logout()
                .logoutUrl("/logout")
                .and()
                .csrf().disable()
                .sessionManagement() // 开启会话管理
                .maximumSessions(1) // 最大会话个数
                // 传统开发
//                .expiredUrl("/login") //当用户被挤下线时候跳转路径
                // 前后端分离的处理方案
                .expiredSessionStrategy(event -> {
                    HttpServletResponse response = event.getResponse();
                    response.setContentType("application/json;charset=UTF-8");
                    Map<String, Object> result = new HashMap<>();
                    result.put("status", 500);
                    result.put("msg", "当前会话已经失效,请重新登录!");
                    String s = new ObjectMapper().writeValueAsString(result);
                    response.setContentType("application/json;charset=UTF-8");
                    response.getWriter().println(s);
                    // 刷新一下
                    response.flushBuffer();
                })
                .sessionRegistry(sessionRegistry()) // 将session交给谁管理
                .maxSessionsPreventsLogin(true);//登录之后禁止再次登录
        ;
    }

    // 创建 session 同步到 redis 中的方案自身就不用这个了
    /*// 监听session
    @Bean
    public HttpSessionEventPublisher httpSessionEventPublisher() {
        return new HttpSessionEventPublisher();
    }*/

    // 创建 session 同步到 redis 中的方案
    @Bean
    public SpringSessionBackedSessionRegistry sessionRegistry() {
        // 需要用到操作session的接口
        return new SpringSessionBackedSessionRegistry(findByIndexNameSessionRepository);
    }
}
